/**
 *    https://gitee.com/gitsc/pro-cloud/
 *     @Author Aijm 2929793435@qq.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.cloud.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.util.CharsetUtil;
import com.cloud.admin.beans.dto.TenantDTO;
import com.cloud.admin.beans.po.OauthClientDetails;
import com.cloud.admin.service.OauthClientDetailsService;
import com.cloud.admin.util.UserUtil;
import com.cloud.common.cache.annotation.RedisLock;
import com.cloud.common.cache.constants.RedisKeys;
import com.cloud.common.cache.redis.RedisDao;
import com.cloud.common.data.base.BaseService;
import com.cloud.admin.beans.po.SysTenant;
import com.cloud.admin.mapper.SysTenantMapper;
import com.cloud.admin.service.SysTenantService;
import com.cloud.common.data.util.IdUtils;
import com.cloud.common.util.util.DateUtils;
import com.cloud.common.util.util.StrUtils;
import com.cloud.common.util.var.StaticVar;
import com.google.common.collect.Maps;
import lombok.SneakyThrows;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;


/**
 * 租户管理
 *
 * @author Aijm
 * @date 2020-05-25 13:32:23
 */
@Service
public class SysTenantServiceImpl extends BaseService<SysTenantMapper, SysTenant> implements SysTenantService {

    @Autowired
    private SysTenantMapper sysTenantMapper;

    @Autowired
    private OauthClientDetailsService oauthClientDetailsService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private RedisDao redisDao;

    /**
     * 获取下一个租户id
     *
     * @return
     */
    @Override
    @RedisLock(key = RedisKeys.TENTANT_ADD)
    public Integer getNextTenantId() {
        Long nextTenantId = redisDao.hmSetIncrement(RedisKeys.TENTANT_ADD, RedisKeys.TENTANT_ADD_HASH, 1L);
        // 可能是清空了的数据 得到的错误 计数器
        if (nextTenantId == 1) {
            Integer maxTenantId = sysTenantMapper.getNextTenantId();
            if (maxTenantId != null) {
                nextTenantId = redisDao.hmSetIncrement(RedisKeys.TENTANT_ADD, RedisKeys.TENTANT_ADD_HASH, maxTenantId.longValue());
            }

        }
        return nextTenantId.intValue();
    }

    /**
     * 保存租户信息
     *
     * @param tenantDTO
     */
    @Override
    @SneakyThrows
    public boolean saveSysTenant(TenantDTO tenantDTO){

        // 如果为租户类型,需要额外添加基础数据
        if (StaticVar.TENANT_TYPE_TENANT.equals(tenantDTO.getType())) {
            ScriptRunner runner = new ScriptRunner(jdbcTemplate.getDataSource().getConnection());
            //下面配置不要随意更改，否则会出现各种问题
            //自动提交
            runner.setAutoCommit(true);
            runner.setFullLineDelimiter(false);
            //每条命令间的分隔符
            runner.setDelimiter(";");
            runner.setSendFullScript(false);
            runner.setStopOnError(false);

            // 获取最终需要执行的sql
            String sql = getSqlString(tenantDTO);
            runner.runScript(new InputStreamReader(new ByteArrayInputStream(sql.getBytes()), CharsetUtil.UTF_8));

        }

        super.save(tenantDTO);
        return oauthClientDetailsService.save(tenantDTO.getOauthClientDetails());
    }

    /**
     * 根据参数获取最终需要执行的sql
     * @param tenantDTO
     * @return
     * @throws IOException
     */
    private String getSqlString(TenantDTO tenantDTO) throws IOException {
        ClassPathResource classPathResource = new ClassPathResource("file/schema_tenant.sql");

        File file = classPathResource.getFile();
        FileReader fileReader = new FileReader(file);
        String sql = fileReader.readString();
        Map<String, String> kvs = Maps.newConcurrentMap();
        kvs.put("tenantId", tenantDTO.getTenantId().toString());
        kvs.put("companyName", tenantDTO.getCompanyName());
        kvs.put("loginName", tenantDTO.getLoginName());
        kvs.put("password", tenantDTO.getPassword());
        kvs.put("userName", tenantDTO.getUserName());
        kvs.put("tenantId", tenantDTO.getTenantId().toString());
        kvs.put("email", StrUtils.isNotBlank(tenantDTO.getEmail())? tenantDTO.getEmail():"");
        kvs.put("phone", StrUtils.isNotBlank(tenantDTO.getPhone())? tenantDTO.getPhone():"");
        kvs.put("mobile", tenantDTO.getMobile());
        kvs.put("createBy", UserUtil.getUserId().toString());
        kvs.put("createDate", DateUtils.getCurrentDateTimeStr());
        sql = StrUtils.format(sql, kvs);
        return sql;
    }
}